import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_first_station/common/dialog.dart';
import 'package:flutter_first_station/paper/paper_app_bar.dart';
import 'package:flutter_first_station/paper/selector.dart';
import 'package:flutter_first_station/storage/sp_storage.dart';

import 'model.dart';

/// 画板
class PaperPage extends StatefulWidget {
  const PaperPage({super.key});

  @override
  State<PaperPage> createState() => _PaperPageState();
}

class _PaperPageState extends State<PaperPage>
    with AutomaticKeepAliveClientMixin {
  final List<Line> _lines = []; // 线列表
  final List<Line> _historyLines = []; // 历史线列表
  int _activeColorIndex = 0; // 颜色索引
  int _activeStrokeWidthIndex = 0; // 线宽索引

  // 支持的颜色
  final List<Color> supportColors = [
    Colors.black,
    Colors.red,
    Colors.orange,
    Colors.yellow,
    Colors.green,
    Colors.blue,
    Colors.indigo,
    Colors.purple,
    Colors.pinkAccent,
    Colors.lightGreen,
    Colors.teal,
    Colors.tealAccent
  ];

  // 支持的线宽
  final List<double> supportStrokeWidths = [1, 2, 4, 6, 8, 10];

  void _showClearDialog() {
    showDialog(
      context: context,
      builder: (ctx) => ConfirmDialog(
        title: "清空提示",
        confirmText: "确定",
        msg: "您的当前操作会清空绘制内容，是否确定删除!",
        onConfirm: _onClear,
      ),
    );
  }

  void _onClear() {
    Navigator.of(context).pop();
    _lines.clear();
    _historyLines.clear();
    setState(() {});
  }

  /// 拖拽开始，添加新线
  void _onPanStart(DragStartDetails details) {
    _lines.add(Line(
        points: [details.localPosition],
        strokeWidth: supportStrokeWidths[_activeStrokeWidthIndex],
        color: supportColors[_activeColorIndex]));
  }

  /// 拖拽中，为新线添加点
  void _onPanUpdate(DragUpdateDetails details) {
    Offset point = details.localPosition;
    double distance = (_lines.last.points.last - point).distance;
    // 过滤相近的点
    if (distance > 5) {
      _lines.last.points.add(details.localPosition);
      setState(() {});
    }
  }

  /// 选择线宽
  void _onSelectStrokeWidth(int index) {
    if (index != _activeStrokeWidthIndex) {
      setState(() {
        _activeStrokeWidthIndex = index;
        saveConfig();
      });
    }
  }

  /// 选择颜色
  void _onSelectColor(int index) {
    if (index != _activeColorIndex) {
      setState(() {
        _activeColorIndex = index;
        saveConfig();
      });
    }
  }

  /// 回退
  void _back() {
    Line line = _lines.removeLast();
    _historyLines.add(line);
    setState(() {});
  }

  /// 撤销
  void _revocation() {
    Line line = _historyLines.removeLast();
    _lines.add(line);
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    _initConfig();
  }

  void saveConfig() {
    SpStorage.instance.savePaper(
        activeColorIndex: _activeColorIndex,
        activeStrokeWidthIndex: _activeStrokeWidthIndex);
  }

  void _initConfig() async {
    Map<String, dynamic> config = await SpStorage.instance.readPaperConfig();
    _activeColorIndex = config["activeColorIndex"] ?? 0;
    _activeStrokeWidthIndex = config["activeStrokeWidthIndex"] ?? 0;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PaperAppBar(
        onClear: _showClearDialog,
        onBack: _lines.isEmpty ? null : _back,
        onRevocation: _historyLines.isEmpty ? null : _revocation,
      ),
      // 监听手势回调
      body: Stack(
        children: [
          GestureDetector(
            onPanStart: _onPanStart,
            onPanUpdate: _onPanUpdate,
            // 自定义绘制，就是指继承 CustomPainter 完成绘制逻辑，比如这里的 PaperPainter 画板
            // 画布的尺寸填充剩余空间，可以将 child 指定为 ConstrainedBox ，并通过 BoxConstraints.expand() 的约束
            child: CustomPaint(
              painter: PaperPainter(lines: _lines),
              child: ConstrainedBox(constraints: const BoxConstraints.expand()),
            ),
          ),
          Positioned(
              bottom: 0,
              width: MediaQuery.of(context).size.width, // 指定约束尺寸为屏幕宽度
              child: Row(
                children: [
                  Expanded(
                      child: ColorSelector(
                    supportColors: supportColors,
                    activeIndex: _activeColorIndex,
                    onSelect: _onSelectColor,
                  )),
                  StrokeWidthSelector(
                    supportStrokeWidths: supportStrokeWidths,
                    color: supportColors[_activeColorIndex],
                    activeIndex: _activeStrokeWidthIndex,
                    onSelect: _onSelectStrokeWidth,
                  )
                ],
              )),
        ],
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}

/// 自定义绘制
class PaperPainter extends CustomPainter {
  PaperPainter({required this.lines}) {
    _paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;
  }

  late Paint _paint;
  final List<Line> lines;

  @override
  void paint(Canvas canvas, Size size) {
    for (int i = 0; i < lines.length; i++) {
      drawLine(canvas, lines[i]);
    }
  }

  /// 根据点集绘制线
  void drawLine(Canvas canvas, Line line) {
    _paint.color = line.color;
    _paint.strokeWidth = line.strokeWidth;
    canvas.drawPoints(PointMode.polygon, line.points, _paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
